﻿using Dotnet.Utils.Utility.Serialize;
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security.Cryptography;
using System.Text;

namespace Dotnet.Utils.Utility.EncryptUtil
{
    public sealed class CryptoUtil
    {
        public static string UrlEncodeBase64String(string sBase64String)
        {
            StringBuilder stringBuilder = new StringBuilder(sBase64String);
            stringBuilder.Replace("=", "_0").Replace("+", "_1").Replace("/", "_2");
            return stringBuilder.ToString();
        }

        public static string UrlDecodeBase64String(string sUrlEncodeString)
        {
            StringBuilder stringBuilder = new StringBuilder(sUrlEncodeString);
            stringBuilder.Replace("_0", "=").Replace("_1", "+").Replace("_2", "/");
            return stringBuilder.ToString();
        }

        public static string SerializeUrlString(object obj)
        {
            return UrlEncodeBase64String(Convert.ToBase64String(SerializeUtil.BinarySerialize(obj)));
        }

        public static object DeserializeUrlString(string sUrlString)
        {
            return SerializeUtil.BinaryDeserialize(Convert.FromBase64String(UrlDecodeBase64String(sUrlString)));
        }

        public static string EncodeBase64(object o)
        {
            string result;
            using (MemoryStream memoryStream = new MemoryStream())
            {
                IFormatter formatter = new BinaryFormatter();
                formatter.Serialize(memoryStream, o);
                byte[] buffer = memoryStream.GetBuffer();
                result = Convert.ToBase64String(buffer);
            }
            return result;
        }

        public static object DecodeBase64ToObject(string strBase64)
        {
            byte[] buffer = Convert.FromBase64String(strBase64);
            object result;
            using (MemoryStream memoryStream = new MemoryStream(buffer))
            {
                IFormatter formatter = new BinaryFormatter();
                result = formatter.Deserialize(memoryStream);
            }
            return result;
        }

        public static string GetMD5(string sourceStr)
        {
            byte[] bytes = Encoding.Unicode.GetBytes(sourceStr);
            return GetMD5(bytes);
        }

        public static string GetMD5(byte[] buffer)
        {
            MD5CryptoServiceProvider md5CryptoServiceProvider = new MD5CryptoServiceProvider();
            byte[] value = md5CryptoServiceProvider.ComputeHash(buffer);
            return BitConverter.ToString(value);
        }

        public static string GetMD5(object obj)
        {
            return GetMD5(SerializeUtil.BinarySerialize(obj));
        }

        public static string MD5File(string fileName)
        {
            string result;
            using (FileStream fileStream = File.OpenRead(fileName))
            {
                result = MD5Stream(fileStream);
            }
            return result;
        }

        public static string MD5Stream(Stream stream)
        {
            stream.Position = 0L;
            MD5 md = new MD5CryptoServiceProvider();
            byte[] buffer = md.ComputeHash(stream);
            return GetMD5(buffer);
        }

        public static string GetMD5HashString(string sourceString)
        {
            return GetMD5HashString(Encoding.Unicode, sourceString);
        }

        public static string GetMD5HashString(Encoding encode, string sourceString)
        {
            MD5CryptoServiceProvider md5CryptoServiceProvider = new MD5CryptoServiceProvider();
            byte[] array = md5CryptoServiceProvider.ComputeHash(encode.GetBytes(sourceString));
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < array.Length; i++)
            {
                stringBuilder.Append(array[i].ToString("x2"));
            }
            return stringBuilder.ToString().ToUpper();
        }

        public static string GetSHA(string sourceStr)
        {
            byte[] bytes = Encoding.Default.GetBytes(sourceStr);
            return GetSHA(bytes);
        }

        public static string GetSHA(byte[] buffer)
        {
            SHA1 sha = new SHA1CryptoServiceProvider();
            byte[] value = sha.ComputeHash(buffer);
            return BitConverter.ToString(value);
        }

        public static string GetDes(string encryptString, string encryptKey, string iv)
        {
            string result;
            try
            {
                if (encryptKey.Length < 8)
                {
                    encryptKey = encryptKey.PadLeft(8, '*');
                }
                if (iv.Length < 8)
                {
                    iv = iv.PadLeft(8, '*');
                }
                byte[] bytes = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
                byte[] bytes2 = Encoding.UTF8.GetBytes(iv.Substring(0, 8));
                byte[] bytes3 = Encoding.UTF8.GetBytes(encryptString);
                DESCryptoServiceProvider descryptoServiceProvider = new DESCryptoServiceProvider();
                MemoryStream memoryStream = new MemoryStream();
                CryptoStream cryptoStream = new CryptoStream(memoryStream, descryptoServiceProvider.CreateEncryptor(bytes, bytes2), CryptoStreamMode.Write);
                cryptoStream.Write(bytes3, 0, bytes3.Length);
                cryptoStream.FlushFinalBlock();
                result = Convert.ToBase64String(memoryStream.ToArray());
            }
            catch
            {
                result = encryptString;
            }
            return result;
        }

        public static string FromDes(string decryptString, string decryptKey, string iv)
        {
            string result;
            try
            {
                if (decryptKey.Length < 8)
                {
                    decryptKey = decryptKey.PadLeft(8, '*');
                }
                if (iv.Length < 8)
                {
                    iv = iv.PadLeft(8, '*');
                }
                byte[] bytes = Encoding.UTF8.GetBytes(decryptKey);
                byte[] bytes2 = Encoding.UTF8.GetBytes(iv.Substring(0, 8));
                byte[] array = Convert.FromBase64String(decryptString);
                DESCryptoServiceProvider descryptoServiceProvider = new DESCryptoServiceProvider();
                MemoryStream memoryStream = new MemoryStream();
                CryptoStream cryptoStream = new CryptoStream(memoryStream, descryptoServiceProvider.CreateDecryptor(bytes, bytes2), CryptoStreamMode.Write);
                cryptoStream.Write(array, 0, array.Length);
                cryptoStream.FlushFinalBlock();
                result = Encoding.UTF8.GetString(memoryStream.ToArray());
            }
            catch
            {
                result = decryptString;
            }
            return result;
        }

        public static string RSADecrypt(string xmlPrivateKey, string m_strDecryptString)
        {
            RSACryptoServiceProvider rsacryptoServiceProvider = new RSACryptoServiceProvider();
            rsacryptoServiceProvider.FromXmlString(xmlPrivateKey);
            int num = rsacryptoServiceProvider.KeySize / 8;
            byte[] array = Convert.FromBase64String(m_strDecryptString);
            if (array.Length > num)
            {
                using (MemoryStream memoryStream = new MemoryStream(array))
                {
                    using (MemoryStream memoryStream2 = new MemoryStream())
                    {
                        byte[] array2 = new byte[num];
                        for (int i = memoryStream.Read(array2, 0, num); i > 0; i = memoryStream.Read(array2, 0, num))
                        {
                            byte[] array3 = new byte[i];
                            Array.Copy(array2, 0, array3, 0, i);
                            byte[] array4 = rsacryptoServiceProvider.Decrypt(array3, false);
                            memoryStream2.Write(array4, 0, array4.Length);
                        }
                        return new UTF8Encoding().GetString(memoryStream2.ToArray());
                    }
                }
            }
            byte[] bytes = rsacryptoServiceProvider.Decrypt(array, false);
            return new UTF8Encoding().GetString(bytes);
        }

        public static string RSAEncrypt(string xmlPublicKey, string m_strEncryptString)
        {
            RSACryptoServiceProvider rsacryptoServiceProvider = new RSACryptoServiceProvider();
            int num = rsacryptoServiceProvider.KeySize / 8 - 11;
            rsacryptoServiceProvider.FromXmlString(xmlPublicKey);
            byte[] bytes = new UTF8Encoding().GetBytes(m_strEncryptString);
            if (m_strEncryptString.Length > num)
            {
                using (MemoryStream memoryStream = new MemoryStream(bytes))
                {
                    using (MemoryStream memoryStream2 = new MemoryStream())
                    {
                        byte[] array = new byte[num];
                        for (int i = memoryStream.Read(array, 0, num); i > 0; i = memoryStream.Read(array, 0, num))
                        {
                            byte[] array2 = new byte[i];
                            Array.Copy(array, 0, array2, 0, i);
                            byte[] array3 = rsacryptoServiceProvider.Encrypt(array2, false);
                            memoryStream2.Write(array3, 0, array3.Length);
                        }
                        return Convert.ToBase64String(memoryStream2.ToArray(), Base64FormattingOptions.None);
                    }
                }
            }
            return Convert.ToBase64String(rsacryptoServiceProvider.Encrypt(bytes, false));
        }

        public static string RSAEncrypt(AsymmetricAlgorithm key, string m_strEncryptString)
        {
            RSACryptoServiceProvider rsacryptoServiceProvider = key as RSACryptoServiceProvider;
            int num = rsacryptoServiceProvider.KeySize / 8 - 11;
            byte[] bytes = new UTF8Encoding().GetBytes(m_strEncryptString);
            if (m_strEncryptString.Length > num)
            {
                using (MemoryStream memoryStream = new MemoryStream(bytes))
                {
                    using (MemoryStream memoryStream2 = new MemoryStream())
                    {
                        byte[] array = new byte[num];
                        for (int i = memoryStream.Read(array, 0, num); i > 0; i = memoryStream.Read(array, 0, num))
                        {
                            byte[] array2 = new byte[i];
                            Array.Copy(array, 0, array2, 0, i);
                            byte[] array3 = rsacryptoServiceProvider.Encrypt(array2, false);
                            memoryStream2.Write(array3, 0, array3.Length);
                        }
                        return Convert.ToBase64String(memoryStream2.ToArray(), Base64FormattingOptions.None);
                    }
                }
            }
            return Convert.ToBase64String(rsacryptoServiceProvider.Encrypt(bytes, false));
        }

        public static string RSADecrypt(AsymmetricAlgorithm key, string m_strDecryptString)
        {
            RSACryptoServiceProvider rsacryptoServiceProvider = key as RSACryptoServiceProvider;
            int num = rsacryptoServiceProvider.KeySize / 8;
            m_strDecryptString = m_strDecryptString.Replace(' ', '+');
            byte[] array = Convert.FromBase64String(m_strDecryptString);
            if (array.Length > num)
            {
                using (MemoryStream memoryStream = new MemoryStream(array))
                {
                    using (MemoryStream memoryStream2 = new MemoryStream())
                    {
                        byte[] array2 = new byte[num];
                        for (int i = memoryStream.Read(array2, 0, num); i > 0; i = memoryStream.Read(array2, 0, num))
                        {
                            byte[] array3 = new byte[i];
                            Array.Copy(array2, 0, array3, 0, i);
                            byte[] array4 = rsacryptoServiceProvider.Decrypt(array3, false);
                            memoryStream2.Write(array4, 0, array4.Length);
                        }
                        return new UTF8Encoding().GetString(memoryStream2.ToArray());
                    }
                }
            }
            byte[] bytes = rsacryptoServiceProvider.Decrypt(array, false);
            return new UTF8Encoding().GetString(bytes);
        }
    }
}